#include <stddef.h>
#include <stdio.h>

#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#ifndef _MSC_VER
 #include <unistd.h>
#endif

#include "typedfs.h"
#include "image.h"
#include "imageop.h"

#ifndef __UNIX__
// #include <io.h>
#endif

#include <matrix.h>


//#ifdef RasImg
//#include <alloc.h>

extern Image LoadPicture(const char *Name);
extern int SavePicture(const char *Name,const Image &Img);



const char *GetExtension(const char *FullName)
{
const char *NameStep;
int LastPos;

if(FullName==NULL) return(NULL);

LastPos=strlen(FullName);
NameStep=FullName+LastPos+1;
while(NameStep>FullName)
	{
	NameStep--;

	if(*NameStep=='/' || *NameStep=='\\' || *NameStep==':')
		break;
	if(*NameStep=='.')
		return(NameStep);
	}

return(FullName+LastPos);
}


/////////////////////Main CODE starts here/////////////////////////////////

char Verbosity = 0;

void PrintHeader(void)
{
char HdrPrinted=0;
  if(Verbosity>=0 && HdrPrinted==0)
    {
    puts("\n\r <<< HISTFIX >>> Check image histogram (c)1997-2025 F&TSoft ");
    HdrPrinted=1;
    }
}


int main(int argc,char *argv[])
{
Image I1,I2;
const char *InputImg=NULL, *OutputImg=NULL;
const char *s;
//const char *OutFormat=NULL;
TImageFileHandler *LoadPicture_XXX;
int i;
int PeelPlaneNo = -1;
bool Conv2Gray = false;
int Error = 0;
int DoUnlink = 0;

	/* Parse Arguments */
for(i=1;i<argc;i++)
  {
  s=argv[i];
  if(s==NULL) continue;
  if(*s==0) continue;

  if(*s=='-' || *s=='/')
    {
    if(strcmp(s+1,"help")==0 || strcmp(s+1,"-help")==0 || strcmp(s+1,"?")==0)
      {
        PrintHeader();
        printf("\n");
        for(LoadPicture_XXX=TImageFileHandler::first();LoadPicture_XXX!=NULL;LoadPicture_XXX=LoadPicture_XXX->next())
	  {
	  printf("%s%s%s %s%s; ",LoadPicture_XXX->extension(),
			LoadPicture_XXX->description()==NULL?"":"#",
			LoadPicture_XXX->description()==NULL?"":LoadPicture_XXX->description(),
			LoadPicture_XXX->LoadPicture==NULL?"":"R",
			LoadPicture_XXX->SavePicture==NULL?"":"W");
	  }
	printf(//"\n/NoScale      - means truncating image data"
	       "\n/Gray         - discards all color informations"
	       //"\n/SEPARATE[R|G|B] - remove one channel from true color images"
	       //"\n/Format \"str\" - specify output format"
	       "\n/PeelPlane n  - cut only plane with number n"
               "\n/unlink       - delete image with zero pixel occurancy less than threshold"
	       "\n/s            - decrease verbosity level"
	       "\n/v            - increase verbosity level"
	       "\n");
        return(0);
      }
    //if(strcmp(s+1,"Format")==0 || strcmp(s+1,"format")==0)
    //  {
    //  OutFormat = argv[++i];
    //  continue;
    //  }
    if(strcmp(s+1,"PeelPlane") == 0)
      {
      PeelPlaneNo = atoi(argv[++i]);
      continue;
      }
    if(strcmp(s+1,"unlink") == 0)
      {
      DoUnlink = 1;
      continue;
      }
    if(strcmp(s+1,"s") == 0)
      {
      Verbosity = -1;
      continue;
      }
    if(strcmp(s+1,"v") == 0)
      {
      Verbosity = +1;
      continue;
      }
     if(strcmp(s+1,"Gray") == 0)
     {
       Conv2Gray = true;
       continue;
     }

    }

  if(InputImg==NULL)
     InputImg=s;
  else
     if(OutputImg==NULL) OutputImg=s;
  }
	/* End of reading arguments */

  PrintHeader();
  if(Verbosity>=0) printf("\rLoading");
  //MarkTime=GetInterval();

//for(i=1;i<=10;i++)
  I1 = LoadPicture(InputImg);

  if(I1.Raster==NULL && I1.VecImage==NULL)
	{
	printf("\n\rCannot load input picture:\"%s\" Error %d",InputImg,Error);
	goto End;
	}

  if(Conv2Gray)
  {
    if(Verbosity>=0) printf("\rConverting to gray ");
    Convert2Gray(&I1);
  }

  if(PeelPlaneNo >= 0)
  {
    Image *Im = &I1;
    while(Im != NULL)
    {
      if(Im->Raster!=NULL && Im->Raster->Data2D!=NULL)
      {
        *Im = PeelPlane(*Im, PeelPlaneNo);
        Im->AttachPalette(NULL);
      }
      Im = Im->Next;
    }
  }

  {
  int ZeroPixels = 0;
  float ratio;
  for(unsigned y=0; y<I1.Raster->Size2D; y++)
    for(unsigned x=0; x<I1.Raster->Size1D; x++)
    {
      if(I1.Raster->GetValue2D(x,y)==0) ZeroPixels++;
    }

  ratio = ZeroPixels/((float)I1.Raster->Size2D*I1.Raster->Size1D);

  if(ratio>0.05)
    printf("\nZero pixel ratio %s: %g.", InputImg, ratio);

  if(ratio>0.3)
    if(DoUnlink)
      unlink(InputImg);

  }

End:
  return(Error);

}
//#endif //Ras_img

